package com.xq.model.service.impl;

import cn.hutool.core.math.MathUtil;
import cn.hutool.core.util.StrUtil;
import com.xq.model.entity.TBaseStationState;
import com.xq.model.service.AsyncService;
import com.xq.utils.HttpUtils;
import com.xq.utils.MathUtils;
import com.xq.utils.StringBuffUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * 执行线程任务实现类
 *
 * @author xu
 * 2021/9/1 9:35
 */
@Slf4j
@Service
public class AsyncServiceImpl implements AsyncService {

    @Override
    //@Async("asyncTaskExecutor")
    public CompletableFuture<TBaseStationState> byUrl(String fileUrl) {
        // 得到文件内容
        String res = null;
        try {
            res = HttpUtils.sendGetFile(fileUrl);
        } catch (IOException e) {
            log.error("执行请求状态文件出错，路径为："+fileUrl);
        }
        // 如果结果是正确的
        if(checkRes(res)){
            // 解析文件内容
            return CompletableFuture.completedFuture(getStateByRes(res));
        }
        log.error("解析状态文件出错，路径为："+fileUrl);
        return CompletableFuture.completedFuture(null);
    }

    /**
     * 匹配旧集合
     * @param oldList 旧集合
     * @param stationIdC 站点号
     */
    private TBaseStationState getStateByStationIdC(List<TBaseStationState> oldList,String stationIdC){
        // 当原有集合为空时
        if(oldList == null || oldList.size()==0){
            return new TBaseStationState();
        }
        // 当匹配到了就返回匹配的
        for (TBaseStationState oldState : oldList) {
            if(oldState.getStationIdC().equals(stationIdC)){
                return oldState;
            }
        }
        return new TBaseStationState();
    }

    /**
     * 通过请求结果 解析出对象
     * @param res 请求结果
     *
     */
    private TBaseStationState getStateByRes(String res){
        TBaseStationState stationState = new TBaseStationState();
        // 分成3行
        String[] str= res.split("\r\n");
        // 第一行
        String[] strFirstLine = str[0].split(" ");
        // 设置区站号
        stationState.setStationIdC(strFirstLine[0]);
        // 设置纬度
        stationState.setLat(StringBuffUtil.insert(2,strFirstLine[1],"."));
        // 设置经度
        stationState.setLon(StringBuffUtil.insert(3,strFirstLine[2],"."));
        // 第二行
        String[] strSecondLine = str[1].split(" ");
        // 啊 我要死了 这么多 呜呜呜 谁来帮我
        // 计算机与子站的通信状态是否正常 0：是，1：否
        stationState.setIsNormalComWithSubCommunicationState(strSecondLine[0]);
        // 气压传感器是否开通 0：是，1：否
        stationState.setIsOpenAirPressureSensor(strSecondLine[1]);
        // 气温传感器是否开通 0：是，1：否
        stationState.setIsOpenAirTemperatureSensor(strSecondLine[2]);
        // 湿球温度传感器是否开通 0：是，1：否
        stationState.setIsOpenWetBulbTemperatureSensor(strSecondLine[3]);
        // 湿敏电容传感器是否开通 0：是，1：否
        stationState.setIsOpenHumidityCapacitanceSensor(strSecondLine[4]);
        // 风向传感器是否开通 0：是，1：否
        stationState.setIsOpenWindDirectionSensor(strSecondLine[5]);
        // 风速传感器是否开通 0：是，1：否
        stationState.setIsOpenWindSpeedSensor(strSecondLine[6]);
        // 雨量传感器是否开通 0：是，1：否
        stationState.setIsOpenRainSensor(strSecondLine[7]);
        // 感雨传感器是否开通 0：是，1：否
        stationState.setIsOpenFeelRainSensor(strSecondLine[8]);
        // 草面温度传感器是否开通 0：是，1：否
        stationState.setIsOpenGrassSurfTemperatureSensor(strSecondLine[9]);
        // 地面温度传感器是否开通 0：是，1：否
        stationState.setIsOpenGroundTemperatureSensor(strSecondLine[10]);
        // 5cm地温传感器是否开通 0：是，1：否
        stationState.setIsOpenGroundTemperatureSensor5cm(strSecondLine[11]);
        // 10cm地温传感器是否开通 0：是，1：否
        stationState.setIsOpenGroundTemperatureSensor10cm(strSecondLine[12]);
        // 15cm地温传感器是否开通 0：是，1：否
        stationState.setIsOpenGroundTemperatureSensor15cm(strSecondLine[13]);
        // 20cm地温传感器是否开通 0：是，1：否
        stationState.setIsOpenGroundTemperatureSensor20cm(strSecondLine[14]);
        // 40cm地温传感器是否开通 0：是，1：否
        stationState.setIsOpenGroundTemperatureSensor40cm(strSecondLine[15]);
        // 80cm地温传感器是否开通 0：是，1：否
        stationState.setIsOpenGroundTemperatureSensor80cm(strSecondLine[16]);
        // 160cm地温传感器是否开通 0：是，1：否
        stationState.setIsOpenGroundTemperatureSensor160cm(strSecondLine[17]);
        // 320cm地温传感器是否开通 0：是，1：否
        stationState.setIsOpenGroundTemperatureSensor320cm(strSecondLine[18]);
        // 蒸发传感器是否开通 0：是，1：否
        stationState.setIsOpenVaporizeSensor(strSecondLine[19]);
        // 日照传感器是否开通 0：是，1：否
        stationState.setIsOpenSunSensor(strSecondLine[20]);
        // 能见度传感器是否开通 0：是，1：否
        stationState.setIsOpenVisibilitySensor(strSecondLine[21]);
        // 云量传感器是否开通 0：是，1：否
        stationState.setIsOpenCloudSensor(strSecondLine[22]);
        // 云高传感器是否开通 0：是，1：否
        stationState.setIsOpenCloudHeightSensor(strSecondLine[23]);
        // 总辐射传感器是否开通 0：是，1：否
        stationState.setIsOpenTotalRadiationSensor(strSecondLine[24]);
        // 净全辐射传感器是否开通 0：是，1：否
        stationState.setIsOpenNetTotalRadiationSensor(strSecondLine[25]);
        // 散射辐射传感器是否开通 0：是，1：否
        stationState.setIsOpenScatteredRadiationSensor(strSecondLine[26]);
        // 直接辐射传感器是否开通 0：是，1：否
        stationState.setIsOpenDirectRadiationSensor(strSecondLine[27]);
        // 反射辐射传感器是否开通 0：是，1：否
        stationState.setIsOpenReflectedRadiationSensor(strSecondLine[28]);
        // 紫外辐射传感器是否开通 0：是，1：否
        stationState.setIsOpenUltravioletRadiationSensor(strSecondLine[29]);
        // 备用1传感器是否开通 0：是，1：否
        stationState.setIsOpenSpare1Sensor(strSecondLine[30]);
        // 备用2传感器是否开通 0：是，1：否
        stationState.setIsOpenSpare2Sensor(strSecondLine[31]);
        // 备用3传感器是否开通 0：是，1：否
        stationState.setIsOpenSpare3Sensor(strSecondLine[32]);
        // 备用4传感器是否开通 0：是，1：否
        stationState.setIsOpenSpare4Sensor(strSecondLine[33]);
        // 备用5传感器是否开通 0：是，1：否
        stationState.setIsOpenSpare5Sensor(strSecondLine[34]);
        // 备用6传感器是否开通 0：是，1：否
        stationState.setIsOpenSpare6Sensor(strSecondLine[35]);
        // 子站是否修改了时钟 0：是，1：否
        stationState.setIsUpdateSubClock(strSecondLine[36]);
        // 采集器数据是否正确读取 0：是，1：否
        stationState.setIsReadCollectorData(strSecondLine[37]);
        // 供电方式 0：市电，1：备份电源，/：不能获取
        stationState.setPowerSupplyMode(strSecondLine[38]);
        // 单位：V，保留1位小数，位数不足时，高位补“0”，不能获取时，用“////”表示
        stationState.setCollectorMainboardVoltage(strSecondLine[39]);
        // 单位：℃，保留1位小数，位数不足时，高位补“0”，不能获取时，用“////”表示
        stationState.setCollectorMainboardTemperature(strSecondLine[40].replace("=",""));
        // 采集器电池电量 百分比 如果能获取到电压就设置电量
        if(!strSecondLine[39].equals("////")){
            stationState.setCollectorMainboardElectric(getElectric(strSecondLine[39]));
        }
        return stationState;
    }

    /**
     * 根据电压获取电量
     * @param voltage 电压
     */
    private String getElectric(String voltage){
        double value = Double.parseDouble(voltage);
        // 电压除以 15 并保留2位小数
        return MathUtils.except(value,15,2);
    }


    /**
     * 检查数据是否正确
     * @param res
     * @return
     */
    private boolean checkRes(String res){
        // 如果开始就空 那就直接返回false
        if(StrUtil.isBlank(res)){
            return false;
        }
        String[] str= res.split("\r\n");
        // 如果没有正确返回3行 就返回
        if(str.length != 3){
            return false;
        }
        // 如果第一行 没有正确返回20个字节 就返回
        if(str[0].length() != 20){
            return false;
        }
        // 如果第二行 没有正确返回88个字节 就返回
        if(str[1].length() != 88){
            return false;
        }

        // 第一行
        String[] strFirstLine = str[0].split(" ");
        // 如果第一行没有解析出3个数
        if(strFirstLine.length!=3){
            return false;
        }
        // 区站号不对
        if(strFirstLine[0].length() != 5){
            return false;
        }
        // 纬度不对
        if(strFirstLine[1].length() != 6){
            return false;
        }
        // 经度不对
        if(strFirstLine[2].length() != 7){
            return false;
        }

        // 第二行
        String[] strSecondLine = str[1].split(" ");
        // 如果第二行没有解析出41个数
        if(strSecondLine.length!=41){
            return false;
        }
        // 第一位数到39位都为 1 个字节
        for(int i=0;i<39;i++){
            if(strSecondLine[i].length()!=1){
                return false;
            }
        }

        // 第40位是 4个字节
        if(strSecondLine[39].length() !=4){
            return false;
        }

        // 第40位是 5个字节  因为还有一个 = 号
        if(strSecondLine[40].length() !=5){
            return false;
        }
        // 如果以上都检测过
        return true;
    }
}
